using System;
using System.Collections.Generic;
using System.Text;
using Microsoft.Xna.Framework;

namespace XnaDevRu.BulletX
{
	/// <summary>
	/// IndexedMesh indexes into existing vertex and index arrays, in a similar way OpenGL glDrawElements
	/// instead of the number of indices, we pass the number of triangles
	/// todo: explain with pictures
	/// </summary>
	public struct IndexedMesh
	{
		private int _numTriangles;
		private int[] _triangleIndexBase;
		private int _triangleIndexStride;
		private int _numVertices;
		private float[] _vertexBase;
		private int _vertexStride;

		public int TriangleCount { get { return _numTriangles; } set { _numTriangles = value; } }
		public int[] TriangleIndexBase { get { return _triangleIndexBase; } set { _triangleIndexBase = value; } }
		public int TriangleIndexStride { get { return _triangleIndexStride; } set { _triangleIndexStride = value; } }
		public int VertexCount { get { return _numVertices; } set { _numVertices = value; } }
		public float[] VertexBase { get { return _vertexBase; } set { _vertexBase = value; } }
		public int VertexStride { get { return _vertexStride; } set { _vertexStride = value; } }
	}

	/// <summary>
	/// TriangleIndexVertexArray allows to use multiple meshes, by indexing into existing triangle/index arrays.
	/// Additional meshes can be added using addIndexedMesh
	/// No duplcate is made of the vertex/index data, it only indexes into external vertex/index arrays.
	/// So keep those arrays around during the lifetime of this btTriangleIndexVertexArray.
	/// </summary>
	public class TriangleIndexVertexArray : StridingMeshInterface
	{
		List<IndexedMesh> _indexedMeshes = new List<IndexedMesh>();

		public TriangleIndexVertexArray() { }

		public TriangleIndexVertexArray(int numTriangleIndices, int[] triangleIndexBase, int triangleIndexStride, int numVertices, float[] vertexBase, int vertexStride)
		{
			IndexedMesh mesh = new IndexedMesh();
			mesh.TriangleCount = numTriangleIndices;
			mesh.TriangleIndexBase = triangleIndexBase;
			mesh.TriangleIndexStride = triangleIndexStride;
			mesh.VertexBase = vertexBase;
			mesh.VertexCount = numVertices;
			mesh.VertexStride = vertexStride;

			AddIndexedMesh(mesh);
		}

		public void AddIndexedMesh(IndexedMesh indexedMesh)
		{
			_indexedMeshes.Add(indexedMesh);
		}

		public override void GetLockedVertexIndexBase(out List<Vector3> verts, out List<int> indicies, out int numfaces, int subpart)
		{
			throw new Exception("The method or operation is not implemented.");
		}

		public override void GetLockedReadOnlyVertexIndexBase(out List<Vector3> verts, out List<int> indicies, out int numfaces, int subpart)
		{
			throw new Exception("The method or operation is not implemented.");
		}

		public override void UnLockVertexBase(int subpart)
		{
			throw new Exception("The method or operation is not implemented.");
		}

		public override void UnLockReadOnlyVertexBase(int subpart)
		{
			throw new Exception("The method or operation is not implemented.");
		}

		public override int SubPartsCount()
		{
			return _indexedMeshes.Count;
		}

		public override void PreallocateVertices(int numverts)
		{
			throw new Exception("The method or operation is not implemented.");
		}

		public override void PreallocateIndices(int numindices)
		{
			throw new Exception("The method or operation is not implemented.");
		}
	}
}
